package com.xbell.app.sys.common;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.query.Query;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;

import javax.persistence.EntityManager;
import javax.persistence.Parameter;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 前台表格数据
 * @author 王文胜
 *
 */
public class GridDataSet<T> implements java.io.Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = -3590374674104095423L;
	
	/**
	 * 空表格
	 */
	public static GridDataSet<Object> emptyGrid = new GridDataSet<Object>();
	
	private Object extra;
	// 总条数
	private int records;
	/// 总页数
	private int total = 0;
	private int page = 0;

	public void setRowdata(List<T> rowdata) {
		this.rowdata = rowdata;
	}

	private List<T> rowdata = null;

	/**
	 * 前台表格数据
	 * @param inQuery
	 * @param pageSize 页大小
	 * @param pageIndex 当前所在页 从1开始
	 */
	public GridDataSet(javax.persistence.Query inQuery,int pageSize,int pageIndex)
	{
		org.hibernate.query.Query q = inQuery.unwrap(org.hibernate.query.Query.class);
		javax.persistence.Query countq = null;
		if(NativeQueryImpl.class.isAssignableFrom(inQuery.getClass()))
		{
			countq = q.getProducer().createNativeQuery(String.format("select count(*) from (%s) res",q.getQueryString()));
		}
		else
		{
			countq = q.getProducer().createQuery(String.format("select count(*) from (%s) res",q.getQueryString()));
		}
		for(Parameter param : inQuery.getParameters())
		{
			if(param.getPosition()==null)
			{
				String name = param.getName();
				Object obj = (Object)inQuery.getParameterValue(param.getName());
				countq.setParameter(param.getName(), obj);
			}
			else
			{
				countq.setParameter(param.getPosition()+1, (Object)inQuery.getParameterValue(param));
			}
		}
		this.records = ((BigDecimal)countq.getSingleResult()).intValue();
		//this.records = q.list().size(); // 总记录数
		this.total = this.records/pageSize;
		if(this.records%pageSize>0)
		{
			this.total++;
		}

		int start = (pageIndex - 1) * pageSize;
		q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		q.setFirstResult(start);
		q.setMaxResults(pageSize);
		this.page = pageIndex;
		this.rowdata = Trans.transformLowerCase(q.list());;
	}



	/**
	 * 前台表格数据(可以排序)
	 * @param inQuery
	 * @param pageInfo
	 *
	 */
	public GridDataSet(javax.persistence.Query inQuery,PageInfo pageInfo)
	{
		int pageIndex = pageInfo.getPage();
		int pageSize = pageInfo.getRows();
		String sort = pageInfo.getSort();
		String ord = pageInfo.getOrd();
		org.hibernate.query.Query q = inQuery.unwrap(org.hibernate.query.Query.class);
		javax.persistence.Query countq = null;
		if(NativeQueryImpl.class.isAssignableFrom(inQuery.getClass()))
		{
			countq = q.getProducer().createNativeQuery(String.format("select count(*) from (%s) res",q.getQueryString()));
		}
		else
		{
			countq = q.getProducer().createQuery(String.format("select count(*) from (%s) res",q.getQueryString()));
		}

		// 如果有排序条件的话，给sql语句增加排序条件
		if (StringUtils.isNotEmpty(sort)) {
			q = q.getProducer().createNativeQuery(String.format("select * from (%s) order by %s %s", q.getQueryString(), sort , ord));
		}else {
			String sql = q.getQueryString();
			// 如果查询中有px字段的话，默认按照px排序，没有的话默认按照optime排序
			if (sql.contains("px") || sql.contains("PX")) {
				q = q.getProducer().createNativeQuery(String.format("select * from (%s) order by %s asc", q.getQueryString(), "px"));
			}else {
				if (sql.contains("optime")||sql.contains("OPTIME")) {
					q = q.getProducer().createNativeQuery(String.format("select * from (%s) order by %s %s", q.getQueryString(), "optime", "desc"));
				}
			}
			if (sql.contains("fbsj") || sql.contains("FBSJ")) {

				q = q.getProducer().createNativeQuery(String.format("%s ,fbsj desc", q.getQueryString()));
			}
		}
		for(Parameter param : inQuery.getParameters())
		{
			if(param.getPosition()==null)
			{
				String name = param.getName();
				Object obj = (Object)inQuery.getParameterValue(param.getName());
				countq.setParameter(param.getName(), obj);
				q.setParameter(param.getName(), obj);
			}
			else
			{
				countq.setParameter(param.getPosition()+1, (Object)inQuery.getParameterValue(param));
				q.setParameter(param.getPosition()+1, (Object)inQuery.getParameterValue(param));
			}
		}
		// 是否查询全部，是的话，不进行分页和数据条数查询（用户导出）
		if (!pageInfo.isAll()) {
			this.records = ((BigDecimal)countq.getSingleResult()).intValue();
			//this.records = q.list().size(); // 总记录数
			this.total = this.records/pageSize;
			if(this.records%pageSize>0)
			{
				this.total++;
			}

			int start = (pageIndex - 1) * pageSize;
			q.setFirstResult(start);
			q.setMaxResults(pageSize);
			this.page = pageIndex;
		}
		q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		this.rowdata = Trans.transformLowerCase(q.list());
	}

	/**
	 * 前台表格数据(可以排序)
	 *
	 * @param entityManager 实体管理器(必传)
	 * @param sql           sql(必传)
	 * @param paramsObj     实体类参数映射(非必传)
	 * @param paramsMap     Map参数映射(非必传)
	 * @param pageInfo      页面信息(必传)
	 * @return
	 * @author GXY
	 * @date 2023/06/07
	 */
	public GridDataSet(EntityManager entityManager, String sql, Object paramsObj, Map<String, Object> paramsMap, PageInfo pageInfo)
	{
		int pageIndex = pageInfo.getPage();
		int pageSize = pageInfo.getRows();
		String sort = pageInfo.getSort();
		String ord = pageInfo.getOrd();
		String ysql = sql;
		// 如果有排序条件的话，给sql语句增加排序条件
		if (StringUtils.isNotEmpty(sort)) {
			sql = String.format("select * from (%s) order by %s %s", sql, sort , ord);
		}
		Query q = entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class);
		if (paramsObj != null) {
			q.setProperties(paramsObj);
		}
		if (paramsMap != null) {
			q.setProperties(paramsMap);
		}
		Query countq = entityManager.createNativeQuery(String.format("select count(*) from (%s) res", ysql)).unwrap(NativeQueryImpl.class);
		if (paramsObj != null) {
			countq.setProperties(paramsObj);
		}
		if (paramsMap != null) {
			countq.setProperties(paramsMap);
		}

		// 是否查询全部，是的话，不进行分页和数据条数查询（用户导出）
		if (!pageInfo.isAll()) {
			this.records = ((BigDecimal)countq.getSingleResult()).intValue();
			//this.records = q.list().size(); // 总记录数
			this.total = this.records/pageSize;
			if(this.records%pageSize>0)
			{
				this.total++;
			}

			int start = (pageIndex - 1) * pageSize;
			q.setFirstResult(start);
			q.setMaxResults(pageSize);
			this.page = pageIndex;
		}
		q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		this.rowdata = Trans.transformLowerCase(q.list());
	}

	public GridDataSet() {
	}

	/**
	 * 总条数
	 */
	public int getRecords()
	{
		return this.records;
	}
	/**
	 * 总页数
	 */
	public int getTotal() {
		return total;
	}

	public void setRecords(int records) {
		this.records = records;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public Object getExtra() {
        return extra;
    }
    public void setExtra(Object extra) {
        this.extra = extra;
    }
    public int getPage() {
		return page;
	}


	public List<T> getRowData() {
		return rowdata;
	}
}
